package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.mq.MQConstants;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.pojo.dto.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import static com.leyou.common.mq.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.mq.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.mq.MQConstants.RoutingKey.ITEM_UP_KEY;


@Service
public class GoodsService {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private com.leyou.item.mapper.SpuMapper spuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;   //消息队列

    /*查询商品信息*/
    public PageResult<SpuDTO> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {
        PageHelper.startPage(page, rows);

        Example example = new Example(Spu.class);


        if (StringUtils.isNoneBlank(key)) {
            example.createCriteria().andLike("name", "%" + key + "%");
        }

        if (saleable != null) {
            example.createCriteria().andEqualTo("saleable", saleable);
        }

        //默认按时间倒序排序
        example.setOrderByClause("update_time DESC");


        List<Spu> spuList = spuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(spuList)) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }

        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(spuList, SpuDTO.class);

        for (SpuDTO spuDTO : spuDTOS) {
            //放入商品品牌名
            BrandDTO brandDTO = brandService.queryById(spuDTO.getBrandId());
            spuDTO.setBrandName(brandDTO.getName());

            //使用种类id数组查询种类集合     遍历种类集合并取出种类对象的名字    再将这些名字用 / 分隔开来，联合成一整个字符串并返回
            String categoryNames = categoryService.queryCategoryByIds(spuDTO.getCategoryIds()).stream().
                    map(CategoryDTO::getName).collect(Collectors.joining("/"));

            spuDTO.setCategoryName(categoryNames);
        }

        PageInfo<Spu> spuPageInfo = new PageInfo<>(spuList);


        return new PageResult<>(spuPageInfo.getTotal(), spuDTOS);
    }

    /**
     * 新增商品
     *
     * @param spuDTO
     */
    @Transactional
    public void addGoods(SpuDTO spuDTO) {
        /*取出商品信息*/
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);

        spu.setId(null);
        spu.setCreateTime(null);
        spu.setSaleable(null);

        int record = spuMapper.insertSelective(spu);
        if (record != 1) {
            throw new LyException(ExceptionEnum.INSERT_GOODS_FAIL);
        }

        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        spuDetailDTO.setSpuId(spu.getId());
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);

        record = spuDetailMapper.insertSelective(spuDetail);
        if (record != 1) {
            throw new LyException(ExceptionEnum.INSERT_GOODS_FAIL);
        }

        List<SkuDTO> skuDTOS = spuDTO.getSkus();

        skuDTOS.forEach(s -> s.setSpuId(spu.getId()));

        List<Sku> skus = BeanHelper.copyWithCollection(skuDTOS, Sku.class);
        if (skus.size() == 0 || skus == null) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }

        record = skuMapper.insertList(skus);
        if (record != skus.size()) {
            throw new LyException(ExceptionEnum.INSERT_GOODS_FAIL);
        }
    }

    /**
     * TODO : 将上下架信息放入消息队列
     * 更新上下架信息，需要同时更新 Spu表与 Sku表
     * @param saleable
     * @param spuId
     */
    @Transactional
    public void updateSaleable(Boolean saleable, Long spuId) {

        Spu spu = new Spu();
        spu.setId(spuId);
        spu.setSaleable(saleable);
        /*更新spu表*/
        int record = spuMapper.updateByPrimaryKeySelective(spu);
        if (record != 1) {
            throw new LyException(ExceptionEnum.RESOURCE_UPLOAD_FAIL);
        }

        /*更新Sku表*/

        /*准备修改的内容*/
        Sku sku = new Sku();
        sku.setEnable(saleable);
        /*准备匹配的条件*/
        Example example = new Example(Sku.class);
        example.createCriteria().andEqualTo("spuId", spuId);

//        List<Sku> skus = skuMapper.select(sku);
        /*根据 example 中的条件 ，来更新 sku的内容*/
        int upNumber = skuMapper.updateByExampleSelective(sku, example);

        record = skuMapper.selectCountByExample(example);
        if (upNumber != record) {
            throw new LyException(ExceptionEnum.RESOURCE_UPLOAD_FAIL);
        }

        //交换机，Routingkey ,消息体
        amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,
                saleable ? ITEM_UP_KEY:ITEM_DOWN_KEY,
                spuId);

    }

    /*商品详情回显，查询spuDetail*/
    public SpuDetailDTO querySpuDetailById(Long spuDetailId) {

        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(spuDetailId);
        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);
    }

    /*商品详情回显，查询sku信息*/
    public List<SkuDTO> querySkuListBySpuId(Long spuId) {

        Sku sku = new Sku();
        sku.setSpuId(spuId);
        List<Sku> skuList = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(skuList)) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skuList, SkuDTO.class);
    }

    /*修改商品，修改过的商品全部改为未上架状态*/
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        Long spuId = spuDTO.getId();
        if (spuId == null) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }

        /*删除sku*/
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        /*查询sku数量*/
        int size = skuMapper.selectCount(sku);
        if (size > 0) {
            /*删除*/
            int count = skuMapper.delete(sku);
            if (size != count) {
                throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
            }
        }

        /*更新spu*/
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setSaleable(false);
        spu.setCreateTime(null);
        spu.setUpdateTime(null);
        int count = spuMapper.updateByPrimaryKey(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        /*更新spuDetail*/
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
        spuDetail.setSpuId(spuId);
        spuDetail.setCreateTime(null);
        spuDetail.setUpdateTime(null);
        count = spuDetailMapper.updateByPrimaryKey(spuDetail);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        /*添加sku*/
        List<Sku> skus = spuDTO.getSkus().stream().map(s->{
            s.setSpuId(spuId);
            s.setEnable(false);
            return BeanHelper.copyProperties(s,Sku.class);
        }).collect(Collectors.toList());
        count = skuMapper.insertList(skus);

        if (count != skus.size()) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    /**
     * 根据spuId查询spu信息
     * @param spuId
     * @return
     */
    public SpuDTO querySpuBySpuId(Long spuId){
        Spu spu = spuMapper.selectByPrimaryKey(spuId);
        if (spu == null){
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spu, SpuDTO.class);
    }

    /**
     * 根据spuId查询spu信息 spuDetail skus信息
     * @param spuId
     * @return
     */
    public SpuDTO querySpuById(Long spuId) {

        SpuDTO spuDTO = querySpuBySpuId(spuId);

        spuDTO.setSpuDetail(querySpuDetailById(spuId));

        spuDTO.setSkus(querySkuListBySpuId(spuId));

        return spuDTO;
    }

    /**
     * 根据skuIds集合查询sku集合
     * @param skuIds
     * @return
     */
    public List<SkuDTO> querySkuListByIds(List<Long> skuIds) {

        List<Sku> skus = skuMapper.selectByIdList(skuIds);
        if (CollectionUtils.isEmpty(skus)){
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skus,SkuDTO.class);
    }

    /**
     * 减库存
     *
     * @param cartMap 商品skuId及数量的map
     */
    @Transactional
    public void minusStock(Map<Long, Integer> cartMap) {
        Set<Long> skuIds = cartMap.keySet();
        //遍历skuId
        for (Long skuId : skuIds) {
            //取出购买数量
            Integer count = cartMap.get(skuId);
            //减库存
            Integer record = skuMapper.minusStock(skuId,count);
            //如果操作行数不是一行，就抛出库存不足的异常
            if (record != 1){
                throw new LyException(ExceptionEnum.STOCK_NOT_ENOUGH);
            }
        }
    }
}
